import { ref, shallowRef, getCurrentInstance, onUnmounted } from 'vue';
import type { Ref } from 'vue';
import { requestManager } from '@/utils/requestManager';

export interface RequestOptions<TData, TParams extends any[]> {
    // 默认参数
    defaultParams?: TParams;
    // 初始数据
    initialData?: TData;
    // 是否自动运行
    manual?: boolean;
    // 轮询间隔（毫秒）
    pollingInterval?: number;
    // 格式化返回数据
    formatResult?: (res: any) => TData;
    // 请求成功回调
    onSuccess?: (data: TData, params: TParams) => void;
    // 请求失败回调
    onError?: (error: Error, params: TParams) => void;
    // 请求前回调
    onBefore?: (params: TParams) => void;
    // 请求完成回调
    onFinally?: (params: TParams, data?: TData, error?: Error) => void;
    // 组件卸载时是否自动取消请求
    cancelOnUnmount?: boolean;
    // 是否在发起新请求时取消正在进行的请求
    cancelPrevious?: boolean;
}

export interface RequestResult<TData, TParams extends any[]> {
    // 请求数据
    data: Ref<TData | undefined>;
    // 加载状态
    loading: Ref<boolean>;
    // 错误信息
    error: Ref<Error | undefined>;
    // 手动触发请求
    run: (...params: TParams) => Promise<TData>;
    // 取消请求
    cancel: () => void;
    // 刷新（使用上一次的参数）
    refresh: () => Promise<TData>;
    // 重置状态
    reset: () => void;
}

const DEFAULT_OPTIONS: Partial<RequestOptions<any, any>> = {
    manual: false,
    pollingInterval: 0,
    cancelOnUnmount: true,
    cancelPrevious: true,
};

export function useRequest<TData, TParams extends any[]>(
    service: (...args: TParams) => Promise<TData>,
    options: RequestOptions<TData, TParams> = {}
): RequestResult<TData, TParams> {
    const {
        defaultParams,
        initialData,
        manual = DEFAULT_OPTIONS.manual,
        pollingInterval = DEFAULT_OPTIONS.pollingInterval,
        formatResult,
        onSuccess,
        onError,
        onBefore,
        onFinally,
        cancelOnUnmount = DEFAULT_OPTIONS.cancelOnUnmount,
        cancelPrevious = DEFAULT_OPTIONS.cancelPrevious,
    } = options;

    // 获取当前组件实例
    const instance = getCurrentInstance();
    const componentId = instance?.uid || Math.random().toString(36).slice(2);

    const data = shallowRef<TData | undefined>(initialData);
    const loading = ref(false);
    const error = shallowRef<Error>();
    const pollingTimer = ref<number>();
    const latestParams = ref<TParams>();
    const currentRequestId = ref<string>();
    const unmountedFlag = ref(false);

    // 生成请求唯一标识
    const generateRequestId = (params: TParams): string => {
        const timestamp = Date.now();
        const randomStr = Math.random().toString(36).slice(2, 8);
        return `${componentId}_${timestamp}_${randomStr}`;
    };

    // 取消轮询
    const stopPolling = () => {
        if (pollingTimer.value) {
            clearTimeout(pollingTimer.value);
            pollingTimer.value = undefined;
        }
    };

    // 取消当前请求
    const cancelCurrentRequest = () => {
        if (currentRequestId.value) {
            requestManager.cancelRequest(currentRequestId.value);
            currentRequestId.value = undefined;
        }
        stopPolling();
    };

    // 开始轮询
    const startPolling = (params: TParams) => {
        stopPolling();
        if (pollingInterval > 0 && !unmountedFlag.value) {
            pollingTimer.value = window.setTimeout(() => {
                run(...params);
            }, pollingInterval);
        }
    };

    // 实际请求函数
    const run = async (...params: TParams): Promise<TData> => {
        // 如果组件已卸载，不发送请求
        if (unmountedFlag.value) {
            return Promise.reject(new Error('Component unmounted'));
        }

        // 保存最新的参数
        latestParams.value = params;
        
        // 请求前回调
        onBefore?.(params);

        // 如果需要，取消之前的请求
        if (cancelPrevious) {
            cancelCurrentRequest();
        }

        // 设置加载状态
        loading.value = true;
        error.value = undefined;

        // 生成新的请求ID
        const reqId = generateRequestId(params);
        currentRequestId.value = reqId;

        try {
            // 将请求添加到管理器
            const controller = new AbortController();
            requestManager.addRequest(reqId, () => controller.abort());

            // 发起请求
            let response = await service(...params);

            // 如果组件已卸载，不处理响应
            if (unmountedFlag.value) {
                return response;
            }

            // 格式化响应数据
            if (formatResult) {
                response = formatResult(response);
            }

            // 更新数据
            data.value = response;

            // 成功回调
            onSuccess?.(response, params);

            // 开始轮询
            startPolling(params);

            return response;
        } catch (e: any) {
            // 如果是取消请求导致的错误，直接返回
            if (e.name === 'AbortError') {
                return Promise.reject(new Error('Request canceled'));
            }

            // 如果组件已卸载，不处理错误
            if (unmountedFlag.value) {
                throw e;
            }

            // 设置错误信息
            error.value = new Error(e.message || 'Request failed');

            // 错误回调
            onError?.(error.value, params);

            throw error.value;
        } finally {
            // 如果组件未卸载，更新状态
            if (!unmountedFlag.value) {
                loading.value = false;
                onFinally?.(params, data.value, error.value);
            }

            // 从请求管理器中移除请求
            requestManager.removeRequest(reqId);
            if (currentRequestId.value === reqId) {
                currentRequestId.value = undefined;
            }
        }
    };

    // 取消请求并清理状态
    const cancel = () => {
        cancelCurrentRequest();
        loading.value = false;
        error.value = undefined;
    };

    // 使用上一次的参数刷新
    const refresh = async (): Promise<TData> => {
        if (latestParams.value) {
            return run(...latestParams.value);
        }
        if (defaultParams) {
            return run(...defaultParams);
        }
        return Promise.reject(new Error('No parameters available for refresh'));
    };

    // 重置状态
    const reset = () => {
        cancel();
        data.value = initialData;
        latestParams.value = undefined;
    };

    // 如果在组件环境中且启用了自动取消，注册卸载钩子
    if (instance && cancelOnUnmount) {
        onUnmounted(() => {
            unmountedFlag.value = true;
            cancelCurrentRequest();
            requestManager.cancelGroup(componentId.toString());
        });
    }

    // 如果不是手动模式且有默认参数，自动运行
    if (!manual && defaultParams) {
        run(...defaultParams);
    }

    return {
        data,
        loading,
        error,
        run,
        cancel,
        refresh,
        reset,
    };
}
